/* 
 * DataStructures.h
 *
 * Created: 09/03/2014 07:39:15
 * Author: Jason
 * Data definitions and structures for both processors.
 *
 */ 
#include <inttypes.h>

#ifndef DATASTRUCTURES_H_
#define DATASTRUCTURES_H_

#ifdef __cplusplus  
  extern "C" {
#endif


//these are cycled though with mode.robotfunction++
//must start at 1 and be contiguous
//NO_OF_ROBOTFUNCTIONS must be correct
#define ROBOTFUNCTION_WAITFORUSER 1
#define ROBOTFUNCTION_DRAGRACE 2
#define ROBOTFUNCTION_LINEFOLLOWER 3
#define ROBOTFUNCTION_WALLFOLLOWER 4
#define ROBOTFUNCTION_MAZESOLVE 5 //not implimented yet
#define ROBOTFUNCTION_MAZESPEEDRUN 6
#define ROBOTFUNCTION_LINECALIBRATE 7
#define ROBOTFUNCTION_WALLCALIBRATE 8

#define NO_OF_ROBOTFUNCTIONS 4

#define CONFIG_LINECOLOUR_BLACK 1
#define CONFIG_LINECOLOUR_WHITE 1

// SPI commands to define what chunk of data is about to move in what direction.
#define SPICMD_REQUEST_LINEDATA 2
#define SPICMD_REQUEST_WALLDATA 3
#define SPICMD_REQUEST_BUTTONDATA 4
#define SPICMD_REQUEST_RF_STRING 5
#define SPICMD_SEND_RF_STRING 6
#define SPICMD_SEND_OLED_STRING 7
#define SPICMD_SEND_ROBOTFUNCTION 8
#define SPICMD_SEND_LEDDATA 9

typedef struct mode_type
{
  uint8_t robotFunction;
  uint8_t dataFresh;
} mode_type;

typedef struct config_type
{
  uint8_t lineColour;
  uint8_t topStraightSpeedAdjust;
  uint8_t topRightAngleSpeedAdjust;
  uint8_t topCurve1SpeedAdjust;
  uint8_t topCurve2SpeedAdjust;
  uint8_t topCurve3SpeedAdjust;
  uint8_t lineSensorCalibrationLevelLow;
  uint8_t lineSensorCalibrationLevelHigh;
  uint16_t wheelResolution;
  uint16_t wheelCircumfrence;

} config_type;

typedef struct lineSensorData_type
{
  uint8_t sensor1;
  uint8_t sensor2;
  uint8_t sensor3;
  uint8_t sensor4;
  uint8_t sensor5;
  uint8_t dataFresh;
} lineSensorData_type;

typedef struct linePositionData_type
{
  signed char linePosition;
  uint8_t LeftMarker;
  uint8_t RightMarker;
  uint8_t dataFresh;
} linePositionData_type;


typedef struct wallSensorData_type
{
  uint8_t sensor1;
  uint8_t sensor2;
  uint8_t sensor3;
  uint8_t sensor4;
  uint8_t sensor5;
  uint8_t sensor6;
  uint8_t dataFresh;
} wallSensorData_type;

#define HCIDATA_LEDSTATE_ON 1         // on or off
#define HCIDATA_LEDSTATE_HEARTBEAT 2  // heartbeat or always on
#define HCIDATA_LEDSTATE_FAST 4       // fast heartbeat or slow
#define HCIDATA_LEDState_BALANCED 8   // 75:25 or 50:50
#define HCIDATA_LEDState_INVERTED 16  // mostly on or mostly off

#define HCIDATA_BUTTONPRESSEDEVENT_BUTTON1_SHORTPRESS 1
#define HCIDATA_BUTTONPRESSEDEVENT_BUTTON2_SHORTPRESS 2
#define HCIDATA_BUTTONPRESSEDEVENT_BUTTON1_LONGPRESS 3
#define HCIDATA_BUTTONPRESSEDEVENT_BUTTON2_LONGPRESS 4
//#define HCIDATA_BUTTONPRESSEDEVENT_BUTTON1AND2_SHORTPRESS 3
//#define HCIDATA_BUTTONPRESSEDEVENT_BUTTON1AND2_LONGPRESS 6  //system reset

typedef struct buttonData_type
{
  uint8_t btnPressedEvent;
  uint8_t dataFresh;
} buttonData_type;  

typedef struct LEDData_type
{
  uint8_t LED1State;
  uint8_t LED2State;
  uint8_t dataFresh;
} LEDData_type;  
 
typedef struct RobotSpeed_type
{
  signed char LeftSpeed;
  signed char RightSpeed;
  uint8_t dataFresh;
} RobotSpeed_type;

typedef struct RobotDistance_type
{
  int16_t LeftDistance;
  int16_t RightDistance;
  uint8_t dataFresh;
} RobotDistance_type;


typedef struct stringData_type
{
  uint8_t data[20];
}stringData_type;


extern volatile lineSensorData_type lineSensorData;
extern volatile lineSensorData_type lineSensorData_cal;
extern volatile wallSensorData_type wallSensorData;
extern volatile wallSensorData_type wallSensorData_cal;
extern volatile buttonData_type buttonData;
extern volatile LEDData_type LEDData;
extern volatile config_type config;
extern volatile mode_type mode;
extern volatile stringData_type OLEDString;
extern volatile stringData_type RFOutString;
extern volatile stringData_type RFInString;

extern volatile RobotSpeed_type robotSpeed;

typedef union URobotDistance_type//assuming systems are both big endian or both little endian
{
  RobotDistance_type robotDistance;
  struct bytesLeft
  {
    uint8_t b1;
    uint8_t b2;
  }bytesLeft;
  struct bytesRight
  {
    uint8_t b1;
    uint8_t b2;
  }bytesRight;
}URobotDistance_type;

extern volatile URobotDistance_type URobotDistance;


#ifdef __cplusplus
  }
#endif

#endif /* DATASTRUCTURES_H_ */